package ilm.framework.domain;

import ilm.framework.assignment.model.AssignmentState;
import ilm.framework.assignment.model.DomainAction;
import ilm.framework.modules.AssignmentModule;
import ilm.framework.modules.IlmModule;

import java.util.Vector;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Observer;

import javax.swing.JPanel;

public abstract class DomainGUI extends JPanel implements Observer {

	/**
	 * @attribute serial version due to javax.swing specification
	 * @attribute the proposition of the assignment shown by this user interface
	 * @attribute the state of the assignment shown by this user interface
	 * @attrubute the list of possible domain actions the user can do
	 */
	private static final long serialVersionUID = 1L;
	protected String _proposition;
	protected AssignmentState _state;
	protected HashMap _actionList;
	
	/**
	 * Defines the assignment-specific data that this user interface must
	 * keep. Also updates the communication among the framework components.
	 * @param proposition
	 * @param curState
	 * @param moduleList
	 */
	public void setAssignment(String proposition, AssignmentState curState, 
								Collection moduleList) {
		_proposition = proposition;
		_state = curState;
		_state.addObserver(this);
		Iterator actionListIterator = _actionList.values().iterator();
		while(actionListIterator.hasNext()){
		    DomainAction action = (DomainAction) actionListIterator.next();
		    action.setState(_state);
            action.deleteObservers();
            Iterator moduleIterator = moduleList.iterator();
            while(moduleIterator.hasNext()){
                IlmModule module = (IlmModule) moduleIterator.next();
                if(module instanceof AssignmentModule) {
                    AssignmentModule assMod = (AssignmentModule)module;
                    if(assMod.getObserverType() != AssignmentModule.OBJECT_OBSERVER) {
                        action.addObserver(assMod);
                    }
                }
            }
		}
		initDomainGUI();
	}
	
	/**
	 * Initialization method to the user interface features (widgets) 
	 * that depend on the assignment to be defined. It is called at the
	 * method "setAssignment", just after the assignment is defined.
	 * 
	 * @see example.ilm.gui.IlmDomainGUI
	 */
	protected abstract void initDomainGUI();

	/**
	 * Initialization method for the domain action list. 
	 * @param the DomainModel which is used by the actions in the list
	 * It is called by the framework just after the constructor method.
	 * 
	 * @see example.ilm.gui.IlmDomainGUI
	 */
	public abstract void initDomainActionList(DomainModel model);
	
	/**
	 * @return a list of domain objects selected by the user.
	 * It is used by authoringGUI to author a new assignment.
	 * 
	 * @see example.ilm.gui.IlmDomainGUI
	 */
	public abstract Vector getSelectedObjects();
	
	/**
	 * @return the current state of the assignment shown by this 
	 * user interface. It is not a final method, so it can be
	 * overriden by the child class to add some behavior.
	 */
	public AssignmentState getCurrentState() {
		return _state;
	}
	
}
